package cn.goour.web.sys.entity

import cn.goour.utils.Regex.RegexUtils
import cn.goour.utils.http.Http
import cn.goour.utils.http.HttpConfig
import cn.goour.web.sys.entity.type.LoginType
import com.fasterxml.jackson.annotation.JsonIgnore
import getRealIp
import getUserAgent
import org.apache.commons.lang3.StringUtils
import org.hibernate.annotations.Fetch
import org.hibernate.annotations.FetchMode
import org.hibernate.validator.constraints.Length
import org.springframework.core.io.ClassPathResource
import java.io.File
import java.io.Serializable
import java.util.*
import javax.persistence.*
import javax.servlet.http.HttpServletRequest
import javax.validation.constraints.NotBlank

@Entity
data class User(
        @field:[Id GeneratedValue(strategy = GenerationType.IDENTITY)]
        var id: Int = 0,
        @field:[NotBlank(message = "昵称不能为空") Length(max = 20, message = "昵称长度不能大于20")]
        var nick: String = "",
        var name: String = "",
        var weiBoUrl: String = "",
        var profileImageUrl: String = "",
        var login: Boolean = true,


        @field:[JsonIgnore JoinColumn(name = "user_id") OneToMany(cascade = arrayOf(CascadeType.ALL), fetch = FetchType.LAZY)]
        var authorizes: List<UserLoginAuthorize> = arrayListOf(),
        @field:[JsonIgnore JoinColumn(name = "user_id") OneToMany(cascade = arrayOf(CascadeType.ALL), fetch = FetchType.LAZY)]
        var logs: List<Log> = arrayListOf()
) : Serializable {
    constructor(weiBoUser: weibo4j.model.User) : this() {
        this.nick = weiBoUser.name
        this.name = weiBoUser.name
        this.weiBoUrl = weiBoUser.getUrl()
        this.profileImageUrl = getUrlPic(weiBoUser.avatarLarge)
    }

    constructor(qqUser: com.qq.connect.javabeans.qzone.UserInfoBean) : this() {
        this.nick = qqUser.nickname
        this.name = qqUser.nickname
        this.profileImageUrl = qqUser.avatar.avatarURL100
    }

    constructor(yiBanUser: cn.yiban.open.common.entity.User) : this() {
        this.nick = yiBanUser.userInfo.yb_username
        this.profileImageUrl = getUrlPic(yiBanUser.userInfo.yb_userhead)
    }

    constructor(weixinUser: com.qq.weixin.open.entity.User) : this() {
        this.nick = weixinUser.nickname
        this.name = weixinUser.nickname
        this.profileImageUrl = getUrlPic(weixinUser.headimgurl)
    }

    fun getHeadImg(): String {
        return "$headImgPath$profileImageUrl"
    }

    fun getUserLoginAuthorizeByLoginType(loginType: LoginType): UserLoginAuthorize? {
        authorizes.forEach {
            if (it.loginType == loginType) {
                return it
            }
        }
        return null
    }

    companion object {
        /**
         * 保存头像图片的地址
         */
        val headImgPath = "images/headImg/"

        fun getUrlPic(url: String): String {
            // 创建保存目录
            val root = ClassPathResource("/static/").file
            val path = File(root, headImgPath)
            if (!path.exists()) {
                path.mkdirs()
            }
            return getUrlPic(path, url)
        }

        fun getUrlPic(savePath: File, url: String): String {
            if (!RegexUtils.isValidUrl(url)) {
                return "default.png"
            }
            val file = getUrlPicFile(savePath, url)

            return file.name
        }

        fun getUrlPicFile(savePath: File, url: String): File {
            val map = hashMapOf(
                    Pair("image/png", ".png"),
                    Pair("image/bmp", ".bmp"),
                    Pair("image/vnd.wap.wbmp", ".wbmp"),
                    Pair("image/gif", ".gif"),
                    Pair("image/x-icon", ".ico"),
                    Pair("image/jpeg", ".jpg"),
                    Pair("image/tiff", ".tiff")
            )
            val config = HttpConfig(url)
            val re = Http.get(config)
            val contentType = config.backHeader["Content-Type"]
            val filename = UUID.randomUUID().toString() + map.getOrDefault(contentType?.get(0) ?: "", ".tmp")
            val file = File(savePath, filename)
            file.writeBytes(re)

            return file
        }
    }

    override fun toString(): String =
            "User(id=$id, nick='$nick', weiBoUrl='$weiBoUrl', profileImageUrl='$profileImageUrl')"

}

fun main(args: Array<String>) {
    val path = File("")
    val re1 = User.getUrlPic(path, "https://static.oschina.net/uploads/space/2017/0727/184316_jh2I_1053085.png")
    val re2 = User.getUrlPic(path, "https://my.oschina.net/build/oschina/community/stylesheets/imgs/mob.png?t=1494996206000")
    val re3 = User.getUrlPic(path, "http://img02.fs.yiban.cn/8522697/avatar/user/200")
    println(re1)
    println(re2)
    println(re3)
}

@Entity
data class UserLoginAuthorize(
        @field:[Id GeneratedValue(strategy = GenerationType.IDENTITY)]
        var id: Int = 0,
        @field:[Column(insertable = false, updatable = false)]
        var user_id: Int = 0,
        @field:[JsonIgnore Fetch(FetchMode.JOIN) ManyToOne(fetch = FetchType.EAGER)]
        var user: User? = null,
        var loginType: LoginType = LoginType.None,// 登录类型
        var identifier: String = "",// 登录帐号：电子邮箱、用户名、手机号、微信id，微博id，qqid
        var credential: String = "",// 登录口令：密码、Token
        var verified: Boolean = false,

        var addIp: String = "",
        @field:[Column(columnDefinition = "Text")]
        var addUa: String = "",
        var addTime: Date = Date()
) : Serializable {
    @field:[Transient]
    lateinit var request: HttpServletRequest

    constructor(token: weibo4j.http.AccessToken) : this() {
        this.identifier = token.uid
        this.credential = token.accessToken
        this.loginType = LoginType.WeiBo
        this.verified = true
    }

    constructor(token: com.qq.connect.javabeans.AccessToken, identifier: String) : this() {
        this.identifier = identifier
        this.credential = token.accessToken
        this.loginType = LoginType.QQ
        this.verified = true
    }

    constructor(token: cn.yiban.open.common.entity.AccessToken) : this() {
        this.identifier = token.userid
        this.credential = token.access_token
        this.loginType = LoginType.YiBan
        this.verified = true
    }

    constructor(token: com.qq.weixin.open.entity.AccessToken) : this() {
        this.identifier = if (StringUtils.isNotEmpty(token.unionid)) {
            token.unionid
        } else {
            token.openid
        }
        this.credential = token.access_token
        this.loginType = LoginType.WeiXin
        this.verified = true
    }


    constructor(token: weibo4j.http.AccessToken, request: HttpServletRequest) : this(token) {
        this.initAdd(request)
    }

    constructor(token: com.qq.connect.javabeans.AccessToken, identifier: String, request: HttpServletRequest) : this(token, identifier) {
        this.initAdd(request)
    }

    constructor(token: cn.yiban.open.common.entity.AccessToken, request: HttpServletRequest) : this(token) {
        this.initAdd(request)
    }

    constructor(token: com.qq.weixin.open.entity.AccessToken, request: HttpServletRequest) : this(token) {
        this.initAdd(request)
    }

    fun initAdd(request: HttpServletRequest) {
        this.request = request
        this.addIp = request.getRealIp()
        this.addUa = request.getUserAgent()
    }

    override fun toString(): String =
            "UserLoginAuthorize(id=$id, user_id=$user_id, loginType='$loginType', identifier='$identifier', credential='$credential', verified=$verified, addIp='$addIp', addUa='$addUa', addTime=$addTime)"

}

